<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>

<body>
    <div id="app">
        <p>count:{{count}}---{{doubleCount}}</p>
        <p>
            <button @click="addCount">count++</button>
            <button @click="doubleCount+=2">doubleCount+2</button>
        </p>
        <hr>
        <p>
            {{zhang.name}}----{{zhang.age}}----{{zhang.info.height}}----{{zhang.info.weight}}
        </p>
        <p>
            <button @click="changeName">changeName</button>
            <button @click="changeAge">changeAge</button>
            <button @click="changeHeight">changeHeight</button>
        </p>
    </div>
</body>
<script>

    // 组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量，并将从多个函数中得到的状态组合起来处理复杂问题

    let { createApp } = Vue;
    let { ref, reactive, readonly, computed, watch } = Vue;


    let app = createApp({
        setup(props) {

            // ref
            var count = ref(10); // {value:10}
            console.log("count", count);

            // reactive (响应式代理)
            var zhang = reactive({ name: "张三", age: 18, info: { height: 177, weight: 70 } });
            console.log("zhang", zhang);

            // 计算属性
            let doubleCount = computed({
                get: () => {
                    return count.value * 2;
                },
                set: (val) => {
                    count.value  = val /  2;
                }
            })
            console.log("doubleCount", doubleCount);

            // 该 ref 通过 .value 取值
            console.log("doubleCount", doubleCount.value);

            // methods
            let addCount = () => {
                count.value++;
            }


            let changeName = () => {
                zhang.name = "李四"
            }

            let changeAge = () => {
                zhang.age++
            }

            let changeHeight = () => {
                zhang.info.height++
            }


 
            // watch监听  => 侦听一个或多个响应式数据源，并在数据源变化时调用所给的回调函数。
            // 1. watch(source,callback)  监听单个数据
            //    source 监听的数据(ref对象 reactive对象 computed, 返回数据的函数)
            //    callback 数据发生改变时触发的回调函数

            // 2. watch([source,source,source],callback)  监听单多数据

            // 监听ref对象
            // watch(count,(newVal,oldVal)=>{
            //     console.log("count发生了改变",newVal,oldVal);
            // })

            // 监听计算属性(ref对象)
            // watch(doubleCount,(newVal,oldVal)=>{
            //     console.log("doubleCount发生了改变",newVal,oldVal);
            // })

            // 监听reactive 响应式代理!!!!!!!!!!!!!!!!
            // watch 监听reactive响应式代理,默认就是深层的,可以监听对象上根属性的改变,如果根属性的值也是一个对象,也可以监听
            // console.log(1111, zhang);
            // console.log(1111, zhang.info);
            // watch(zhang,(newVal,oldVal)=>{
            //     console.log("zhang发生了改变",newVal,oldVal);
            // })

            // 返回数据的函数 => 监听对象上某个属性的改变 (1. 先生成计算属性, 2.在监听属性的改变)
            // watch(()=>zhang.age,(newVal,oldVal)=>{
            //     console.log("zhang.age发生了改变",newVal,oldVal);
            // })

            // 等价于
            // let age = computed(()=>zhang.age);
            // watch(age,(newVal,oldVal)=>{
            //     console.log("zhang.age发生了改变",newVal,oldVal);
            // })

            // 监听多个数据源  => 只要有一个数据源改变,均会触发

            // watch([count,()=>zhang.name,()=>zhang.age],(newVal,oldVal)=>{

            // })

            watch([count,doubleCount,()=>zhang.name,()=>zhang.age],([newCount,newName,newAge],[oldCount,oldName,oldAge])=>{
                console.log("数据发生了改变");
                console.log("new",newCount,newName,newAge);
                console.log("old",oldCount,oldName,oldAge);
            })

          


            return {
                count,
                doubleCount,
                addCount,
                zhang,
                changeName,
                changeAge,
                changeHeight,
            }
        },
        mounted() {
            console.log("代理对象,this", this);

            /*  new Proxy({},{
                 get(){
                     // 判断是否是ref对象  => ref.value
                 },
                 set(){
                     // 判断是否是ref对象   => ref.value = xxx
                 }
             }) */
        },
    })


    app.mount("#app");


</script>

</html>